package com.yungam.other.mes_controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.yungam.common.bean.equip.Equipment;
import com.yungam.common.bean.equip.EquipmentCollectorMap;
import com.yungam.common.bean.process.ProductProcess;
import com.yungam.common.bean.process.ProductionProcess;
import com.yungam.common.bean.process.ProductionProcessOperator;
import com.yungam.common.bean.work_order.WorkOrderProduct;
import com.yungam.common.service.*;
import com.yungam.influxdb.service.CollectInfluxService;
import com.yungam.other.response.ResData;
import com.yungam.other.service.IotService;
import com.yungam.other.service.MesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 获取指定罐号是否采集结束接口
 */
@Slf4j
@RestController
public class ProductSnCanPassController {

    @Resource
    private WorkOrderProductService workOrderProductService;
    @Resource
    private ProductProcessService productProcessService;
    @Resource
    private ProductionProcessService productionProcessService;
    @Resource
    private EquipmentService equipmentService;
    @Resource
    private EquipmentCollectorMapService equipmentCollectorMapService;
    @Resource
    private CollectInfluxService collectInfluxService;
    @Resource
    private ProductionProcessOperatorService productionProcessOperatorService;
    @Resource
    private MesService mesService;
    @Resource
    private IotService iotService;

    @PostMapping("/IMCS/getProductSnCanPass")
    public Map<String, Object> getProductSnCanPass(@RequestBody Map<String, Object> params) {
        log.info("『Mes 调用』采集结束接口");
        log.info("=========『mes数据』{}", new Gson().toJson(params));

        // 参数处理
        String trackingId = String.valueOf(params.get("trackingId")), productSn = String.valueOf(params.get("productSn")),
                processNo = String.valueOf(params.get("processNo"));
        Integer passResult = (Integer) params.get("passResult");
        List<String> operator = (List<String>) params.get("operator");

        log.info("『出站』 productSn === " + productSn + " , processNo === " + processNo);

        // Step 1. 判断产品罐号是否存在
        WorkOrderProduct wop =
                workOrderProductService.getOne(new QueryWrapper<WorkOrderProduct>().eq("product_sn", productSn));
        if (wop == null) {
            log.error("=========『罐号不存在』=========");
            return ResData.error("罐号不存在");
        }

        // Step 2. 根据产品代号、工序号, 判断产品工序是否存在
        ProductProcess pp = productProcessService.getOne(new QueryWrapper<ProductProcess>().eq("product_no", wop.getProductNo())
                .eq("process_no", processNo));
        if (pp == null) {
            log.error("=========『产品工序不存在』=========");
            return ResData.error("产品工序不存在");
        }

        // Step 3. 判断工序质量信息是否存在
        QueryWrapper<ProductionProcess> queryWrapper = new QueryWrapper<ProductionProcess>()
                .eq("product_sn", productSn).eq("process_no", processNo);
        if (StringUtils.isNotBlank(trackingId)) queryWrapper.eq("tracking_id", trackingId);
        ProductionProcess pdProcess = productionProcessService.getOne(queryWrapper);
        if (pdProcess == null) {
            log.error("=========『生产工序质量信息不存在』=========");
            return ResData.error("生产工序质量信息不存在");
        }

        // Step 4. 更新产品工序质量数据
        ProductionProcess newProProcess = new ProductionProcess();
        newProProcess.setQualityId(pdProcess.getQualityId());
        newProProcess.setState(1); // 已完成
        newProProcess.setEndTime(new Date());
        newProProcess.setGood(passResult);
        productionProcessService.updateById(newProProcess);
        log.info("更新『ProductionProcess』表成功");

        // Step 5. 根据工序质量信息中的设备编号, 获取设备信息
        Equipment equipment;
        List<Map<String, Object>> collectData = null;
        // 判断设备是否是检验或者加工设备 即满足 ProductProcess.extra == 1 && ProductionProcess.getEquNo != null
        if (pdProcess.getEquNo() != null && pp.getExtra() != 1) { // 有对应工位的设备
            equipment  = equipmentService.getOne(new QueryWrapper<Equipment>()
                    .eq("equ_number", pdProcess.getEquNo()));

            if (equipment == null || equipment.getEquIp() == null) {
                log.error("=========『设备或设备IP不存在』=========");
                return ResData.error("设备或设备IP不存在");
            }
//             @@@@@ TRA$H Step 6. 保存工序操作人员信息 production_process_operator 表
//            if (equipment.getCurUserId() != null) {
//                User curUser = userService.getById(equipment.getCurUserId());
//                ProductionProcessOperator ppo = productionProcessOperatorService.getById(pdProcess.getQualityId());
//                if (ppo == null) { // 插入
//                    ppo = new ProductionProcessOperator();
//                    ppo.setQualityId(pdProcess.getQualityId());
//                    ppo.setUserId(curUser.getId());
//                    ppo.setName(curUser.getName());
//                    productionProcessOperatorService.save(ppo);
//                    log.info("『保存工序操作人员信息』操作人员 === " + curUser.getName());
//                } else { // 更新
//                    ppo.setUserId(curUser.getId());
//                    ppo.setName(curUser.getName());
//                    productionProcessOperatorService.updateById(ppo);
//                    log.info("『更新工序操作人员信息』操作人员 === " + curUser.getName());
//                }
//            }

            // Step 6. 调用 iot 设备接口, 通知扫码结束
            // 查询对应的采集器 ip
            EquipmentCollectorMap cMap = equipmentCollectorMapService.getOne(new QueryWrapper<EquipmentCollectorMap>()
                    .eq("equ_ip", equipment.getEquIp()));
            if (cMap != null && cMap.getCollectorIp() != null) {
                // 调用 iot
                log.info("『调用IOT接口』扫码结束 => equIp === " + equipment.getEquIp() + " => collectorIp === " + cMap.getCollectorIp());
                iotService.equipScanEndAdvice(equipment.getEquIp(), cMap.getCollectorIp());
            }

            // step 7. 从 influxdb 拿数据
            ProductionProcess endProcess = productionProcessService.getOne(new QueryWrapper<ProductionProcess>()
                    .eq("product_sn", productSn)
                    .eq("process_no", processNo)
                    .eq("equ_no", pdProcess.getEquNo()));
            long start = endProcess.getStartTime().getTime() / 1000, end = endProcess.getEndTime().getTime() / 1000;
            Long[] range = { start, end };
            collectData = collectInfluxService.getCollectData(equipment.getEquIp(), range, 60);
            for (Map<String, Object> item : collectData) {
                item.put("trackingId", trackingId);
                item.put("eqptNo", equipment.getEquNumber());
            }
            log.info("influxdb 数据 {}", new Gson().toJson(collectData));
        }

        // step 8. 存储人员信息到 production_process_operator 表
        log.info("mes传来的人员信息为{}", new Gson().toJson(operator));
        log.info("存储人员信息到 production_process_operator 表");
        if (!operator.isEmpty()) {
            List<ProductionProcessOperator> operators = Lists.newArrayList();
            for (String s : operator) {
                operators.add(new ProductionProcessOperator()
                        .setQualityId(pdProcess.getQualityId())
                        .setUserName(s)
                        .setName(s));
            }
            // 先删除
            log.info("先删除该工序对应的人员信息");
            productionProcessOperatorService.remove(new QueryWrapper<ProductionProcessOperator>()
                    .eq("quality_id", pdProcess.getQualityId()));
            log.info("插入 production_process_operator 表, 插入的数据为{}", new Gson().toJson(operators));
            productionProcessOperatorService.saveBatch(operators);
        }

        // Step 9. 调用 mes 接口 给 mes 发送数据
        log.info("调用 mes 接口 给 mes 发送数据 {}", new Gson().toJson(collectData));
        Map<String, Object> resData = mesService.addCollectData(collectData);
        log.info("mes 结果 {}", new Gson().toJson(resData));
        log.info("======== 过站成功 ========");
        return ResData.success("过站下发指令成功");
    }
}
